package tcln.sors.model.core.criteria;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Truong Chau Lien Ngoc (lienngoc@gmail.com)
 */
public class DefaultSearchCriteria implements SearchCriteria, Serializable {
    private static final long serialVersionUID = 1L;

    protected List<SearchCriterion> criterions = new ArrayList<SearchCriterion>();

    /**
     * {@inheritDoc}
     */
    @Override
    public SearchCriteria add(String property, SearchOperator operator, String... values) {
        return add(new SearchCriterion(property, operator, values));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public SearchCriteria add(String property, SearchOperator operator, Date... values) {
        return add(new SearchCriterion(property, operator, values));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public SearchCriteria add(String property, SearchOperator operator, Enum<?>... values) {
        return add(new SearchCriterion(property, operator, values));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public SearchCriteria add(String property, SearchOperator operator, Number... values) {
        return add(new SearchCriterion(property, operator, values));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public SearchCriteria add(SearchCriterion criterion) {
        criterions.add(criterion);
        return this;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<SearchCriterion> getCriterions() {
        List<SearchCriterion> results = new ArrayList<SearchCriterion>(criterions);
        return results;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<SearchCriterion> findCriterions(String property) {
        List<SearchCriterion> results = new ArrayList<SearchCriterion>();
        for (SearchCriterion criterion : criterions) {
            if (property.equalsIgnoreCase(criterion.getProperty())) {
                results.add(criterion);
            }
        }
        return results;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void clear() {
        criterions.clear();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder("Criteria[\n");
        for (SearchCriterion value : criterions) {
            builder.append(value).append("\n");
        }
        builder.append("]");
        return builder.toString();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public SearchCriterion getCriterion(String property) {
        List<SearchCriterion> criterions = findCriterions(property);
        if (criterions.isEmpty()) {
            return null;
        } else if (criterions.size() > 1) {
            throw new IllegalStateException("More than 1 criterion was found");
        }
        return criterions.get(0);
    }
}
